/*register num*/
#define REG_NUM 10
/*type definition*/
#define UNKNOWN_TYPE -1
#define MISMATCHED_TYPE -2
#define MIS_UNK_TYPE -3
#define UNK_MIS_TYPE -4
#define INT_TYPE 1
#define FLOAT_TYPE 2
#define INT_ARRAY_TYPE 3
#define FLOAT_ARRAY_TYPE 4
#define CHAR_TYPE 5
#define CHAR_ARRAY_TYPE 6
#define VOID_TYPE 7
#define PROCEDURE_TYPE 8
#define FUNCTION_TYPE 9
/*error definition*/
#define INVALID_ID_NAME 1
#define UNDECLARED_VARIABLE 2
#define VARIABLE_DECLARED_TWICE 3
#define MISMATCHED_DATA_TYPE 4
#define INVALID_CONSTANT 5
#define SYNTAX_ERROR 6
#define VARIABLE_WAS_ARRAY_TYPE 7
#define VARIABLE_WAS_NOT_ARRAY_TYPE 8
#define INVALID_ARRAY_INDEX 9
#define INVALID_COMPARISON 10
#define UNDECLARED_FUNCTION_NAME 11
#define FUNCTION_HAS_NO_RETURN_TYPE 12
#define WRONG_ARGUMENT_TYPE 13
#define WRONG_NUMBER_OF_ARGUMENTS 14
#define UNDEFINED_FUNCTION 15
/*elseBlock type*/
#define ELSE_TYPE 1
#define THEN_TYPE 2
/*variable check*/
#define  DECLARED_IN_THIS_SCOPE   1
#define  UNDECLARED_IN_THIS_SCOPE 2

extern Variable var[1030][10];

enum code_ops{WRITE_SP,WRITE_LN,
	      GEN_NUM,  READ_INT,  GET_INT,  WRITE_INT,  ADD_INT,  SUB_INT,  MUL_INT,  DIV_INT,  ASSIGN_INT,  POS_INT,  NEG_INT, ADD_INT_1, SUB_INT_1,
	      GEN_FLOAT,READ_FLOAT,GET_FLOAT,WRITE_FLOAT,ADD_FLOAT,SUB_FLOAT,MUL_FLOAT,DIV_FLOAT,ASSIGN_FLOAT,POS_FLOAT,NEG_FLOAT,
	      READ_CHAR,WRITE_CHAR,
	      IF_LABEL,GEN_LABEL,GOTO,SWITCH_TEST,
	      LOGIC_AND,LOGIC_OR,LOGIC_NOT,
	      GREATER_THAN_INT,GREATER_THAN_EQ_INT,LESS_THAN_INT,LESS_THAN_EQ_INT,CMP_EQUAL_INT,CMP_NOT_EQUAL_INT,
	      GREATER_THAN_FLOAT,GREATER_THAN_EQ_FLOAT,LESS_THAN_FLOAT,LESS_THAN_EQ_FLOAT,CMP_EQUAL_FLOAT,CMP_NOT_EQUAL_FLOAT,
	      SET_FOR_INDEX,GET_FOR_INDEX
	     };

int int_reg_used[REG_NUM];
int float_reg_used[REG_NUM];
int label_num = 0;

int find_allocated_space(int var_num, int var_index, int scope, int* used_scope);

void gen_main(FILE* out)
{
    fprintf(out,"int main()\n");
    fprintf(out,"{\n");
    fprintf(out,"\tINIT__S();\n");
}

void gen_end(FILE* out)
{
    fprintf(out,"\t;\n");
    fprintf(out,"}\n");
}

void gen_code_assign_array(FILE* out,int array_pointer,int array_start[],int array_end[],int type, int dim)
{
    int i;
    if(type==INT_TYPE||type==CHAR_TYPE)
    {
	fprintf(out,"\tI__9 = POP__S();\n");//I__1: value
	for(i=dim-1;i>=0;i--)
	{
	    fprintf(out,"\tI__%d = POP__S() - %d;\n",i+1,array_start[i]);//I__2: index for dim (i+1)
	}
	fprintf(out,"\tI__0 = I__1;\n");
	for(i=1;i<=dim-1;i++)
	{
	    fprintf(out,"\tI__0 = I__0 * %d;\n",array_end[i]-array_start[i]);
	    fprintf(out,"\tI__0 = I__0 + I__%d;\n",i+1);
	}
	fprintf(out,"I__0 = I__0 + %d\n;",array_pointer);
	fprintf(out,"\tASSET__S(I__0,I__9);\n");
    }
    else if(type==FLOAT_TYPE)
    {
	fprintf(out,"\tF__2 = FPOP__S();\n"); //value
	for(i=dim-1;i>=0;i--)
	{
	    fprintf(out,"\tI__%d = POP__S() - %d;\n",i+1,array_start[i]);//I__2: index for dim (i+1)
	}
	fprintf(out,"\tI__0 = I__1;\n");
	for(i=1;i<=dim-1;i++)
	{
	    fprintf(out,"\tI__0 = I__0 * %d;\n",array_end[i]-array_start[i]);
	    fprintf(out,"\tI__0 = I__0 + I__%d;\n",i+1);
	}
	fprintf(out,"I__0 = I__0 + %d\n;",array_pointer);
	fprintf(out,"\tFASSET__S(I__0,F__2);\n");
    }
}

void gen_code_write_array(FILE* out,int array_pointer,int array_start[],int array_end[],int type, int dim)
{
    int i;
    if(type==INT_TYPE)
    {
	for(i=dim-1;i>=0;i--)
	{
	    fprintf(out,"\tI__%d = POP__S() - %d;\n",i+1,array_start[i]);//I__2: index for dim (i+1)
	}
	fprintf(out,"\tI__0 = I__1;\n");
	for(i=1;i<=dim-1;i++)
	{
	    fprintf(out,"\tI__0 = I__0 * %d;\n",array_end[i]-array_start[i]);
	    fprintf(out,"\tI__0 = I__0 + I__%d;\n",i+1);
	}
	fprintf(out,"I__0 = I__0 + %d\n;",array_pointer);
	fprintf(out,"\tI__0 = AVAL__S(I__0);\n");
	fprintf(out,"\tprintf(\"%%d\",I__0);\n");
    }
    else if(type==CHAR_TYPE)
    {
	for(i=dim-1;i>=0;i--)
	{
	    fprintf(out,"\tI__%d = POP__S() - %d;\n",i+1,array_start[i]);//I__2: index for dim (i+1)
	}
	fprintf(out,"\tI__0 = I__1;\n");
	for(i=1;i<=dim-1;i++)
	{
	    fprintf(out,"\tI__0 = I__0 * %d;\n",array_end[i]-array_start[i]);
	    fprintf(out,"\tI__0 = I__0 + I__%d;\n",i+1);
	}
	fprintf(out,"I__0 = I__0 + %d\n;",array_pointer);
	fprintf(out,"\tI__0 = AVAL__S(I__0);\n");
	fprintf(out,"\tprintf(\"%%c\",I__0);\n");
    }
    else
    {
	for(i=dim-1;i>=0;i--)
	{
	    fprintf(out,"\tI__%d = POP__S() - %d;\n",i+1,array_start[i]);//I__2: index for dim (i+1)
	}
	fprintf(out,"\tI__0 = I__1;\n");
	for(i=1;i<=dim-1;i++)
	{
	    fprintf(out,"\tI__0 = I__0 * %d;\n",array_end[i]-array_start[i]);
	    fprintf(out,"\tI__0 = I__0 + I__%d;\n",i+1);
	}
	fprintf(out,"I__0 = I__0 + %d\n;",array_pointer);
	fprintf(out,"\tF__0 = FAVAL__S(I__0);\n");
	fprintf(out,"\tprintf(\"%%.6f\",F__0);\n");
    }
}

void gen_code_read_array(FILE* out,int array_pointer,int array_start[],int array_end[],int type, int dim)
{   
    int i;
    if(type==INT_TYPE)
    {
	for(i=dim-1;i>=0;i--)
	{
	    fprintf(out,"\tI__%d = POP__S() - %d;\n",i+1,array_start[i]);//I__2: index for dim (i+1)
	}
	fprintf(out,"\tI__0 = I__1;\n");
	for(i=1;i<=dim-1;i++)
	{
	    fprintf(out,"\tI__0 = I__0 * %d;\n",array_end[i]-array_start[i]);
	    fprintf(out,"\tI__0 = I__0 + I__%d;\n",i+1);
	}
	fprintf(out,"I__0 = I__0 + %d\n;",array_pointer);
	fprintf(out,"\tscanf(\"%%d\",&I__2);\n");
	fprintf(out,"\tASSET__S(I__0,I__2);\n");
    }
    else if(type==CHAR_TYPE)
    {
	for(i=dim-1;i>=0;i--)
	{
	    fprintf(out,"\tI__%d = POP__S() - %d;\n",i+1,array_start[i]);//I__2: index for dim (i+1)
	}
	fprintf(out,"\tI__0 = I__1;\n");
	for(i=1;i<=dim-1;i++)
	{
	    fprintf(out,"\tI__0 = I__0 * %d;\n",array_end[i]-array_start[i]);
	    fprintf(out,"\tI__0 = I__0 + I__%d;\n",i+1);
	}
	fprintf(out,"I__0 = I__0 + %d\n;",array_pointer);
	fprintf(out,"\tscanf(\"%%c\",&I__2);\n");
	fprintf(out,"\tASSET__S(I__0,I__2);\n");
    }
    else
    {
	for(i=dim-1;i>=0;i--)
	{
	    fprintf(out,"\tI__%d = POP__S() - %d;\n",i+1,array_start[i]);//I__2: index for dim (i+1)
	}
	fprintf(out,"\tI__0 = I__1;\n");
	for(i=1;i<=dim-1;i++)
	{
	    fprintf(out,"\tI__0 = I__0 * %d;\n",array_end[i]-array_start[i]);
	    fprintf(out,"\tI__0 = I__0 + I__%d;\n",i+1);
	}
	fprintf(out,"I__0 = I__0 + %d\n;",array_pointer);
	fprintf(out,"\tscanf(\"%%fd\",&F__0);\n");
	fprintf(out,"\tFASSET__S(I__0,F__0);\n");
    }
}

void gen_code_get_array(FILE* out, int array_pointer, int array_start[], int array_end[], int type, int dim)
{
    int i;
    if(type==INT_TYPE||type==CHAR_TYPE)
    {
	for(i=dim-1;i>=0;i--)
	{
	    fprintf(out,"\tI__%d = POP__S() - %d;\n",i+1,array_start[i]);//I__2: index for dim (i+1)
	}
	fprintf(out,"\tI__0 = I__1;\n");
	for(i=1;i<=dim-1;i++)
	{
	    fprintf(out,"\tI__0 = I__0 * %d;\n",array_end[i]-array_start[i]);
	    fprintf(out,"\tI__0 = I__0 + I__%d;\n",i+1);
	}
	fprintf(out,"I__0 = I__0 + %d\n;",array_pointer);
	fprintf(out,"\tI__0 = AVAL__S(I__0);\n");
	fprintf(out,"\tPUSH__S(I__0);\n");
    }
    else
    {
	for(i=dim-1;i>=0;i--)
	{
	    fprintf(out,"\tI__%d = POP__S() - %d;\n",i+1,array_start[i]);//I__2: index for dim (i+1)
	}
	fprintf(out,"\tI__0 = I__1;\n");
	for(i=1;i<=dim-1;i++)
	{
	    fprintf(out,"\tI__0 = I__0 * %d;\n",array_end[i]-array_start[i]);
	    fprintf(out,"\tI__0 = I__0 + I__%d;\n",i+1);
	}
	fprintf(out,"I__0 = I__0 + %d\n;",array_pointer);
	fprintf(out,"\tF__0 = FAVAL__S(I__0);\n");
	fprintf(out,"\tFPUSH__S(F__0);\n");
    }
}

void gen_float(FILE* out, float f)
{
    fprintf(out,"\tFPUSH__S(%f);\n",f);
}

int gen_code(FILE* out, enum code_ops op, int arg)
{
    switch(op)
    {
	case WRITE_INT:
	    fprintf(out,"\tI__2 = %d;\n",arg);
	    fprintf(out,"\tI__0 = AVAL__S(I__2);\n");
	    fprintf(out,"\tprintf(\"%%d\",I__0);\n");
	    break;
	case READ_INT:
	    fprintf(out,"\tI__2 = %d;\n",arg);
	    fprintf(out,"\tscanf(\"%%d\",&I__0);\n");
	    fprintf(out,"\tASSET__S(I__2,I__0);\n");
	    break;
	case GET_INT:
	    fprintf(out,"\tI__0 = AVAL__S(%d);\n",arg);
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    break;
	case GEN_NUM:
	    fprintf(out,"\tPUSH__S(%d);\n",arg);
	    break;
	case WRITE_SP:
	    fprintf(out,"\tprintf(\" \");\n");
	    break;
	case WRITE_LN:
	    fprintf(out,"\tprintf(\"\\n\");\n");
	    break;
	case ADD_INT:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__0 + I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    break;
	case SUB_INT:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__0 - I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    break;
	case MUL_INT:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__0 * I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    break;
	case DIV_INT:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__0 / I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    break;
	case ASSIGN_INT:
	    fprintf(out,"\tI__2 = %d;\n",arg);
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tASSET__S(I__2,I__0);\n");
	    break;
	case POS_INT:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    break;
	case NEG_INT:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = -I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    break;
	case ADD_INT_1:
	    fprintf(out,"\tI__2 = %d;\n",arg);
	    fprintf(out,"\tI__0 = AVAL__S(I__2);\n");
	    fprintf(out,"\tI__0 = I__0 + 1;\n");
	    fprintf(out,"\tASSET__S(I__2,I__0);\n");
	    break;
	case SUB_INT_1:
	    fprintf(out,"\tI__2 = %d;\n",arg);
	    fprintf(out,"\tI__0 = AVAL__S(I__2);\n");
	    fprintf(out,"\tI__0 = I__0 - 1;\n");
	    fprintf(out,"\tASSET__S(I__2,I__0);\n");
	    break;
	case WRITE_FLOAT:
	    fprintf(out,"\tI__2 = %d;\n",arg);
	    fprintf(out,"\tF__0 = FAVAL__S(I__2);\n");
	    fprintf(out,"\tprintf(\"%%.6f\",F__0);\n");
	    break;
	case READ_FLOAT:
	    fprintf(out,"\tI__2 = %d;\n",arg);
	    fprintf(out,"\tscanf(\"%%f\",&F__0);\n");
	    fprintf(out,"\tFASSET__S(I__2,F__0);\n");
	    break;
	case GET_FLOAT:
	    fprintf(out,"\tF__0 = FAVAL__S(%d);\n",arg);
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    break;
	case ADD_FLOAT:
	    fprintf(out,"\tF__1 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = F__0 + F__1;\n");
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    break;
	case SUB_FLOAT:
	    fprintf(out,"\tF__1 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = F__0 - F__1;\n");
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    break;
	case MUL_FLOAT:
	    fprintf(out,"\tF__1 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = F__0 * F__1;\n");
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    break;
	case DIV_FLOAT:
	    fprintf(out,"\tF__1 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = F__0 / F__1;\n");
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    break;
	case ASSIGN_FLOAT:
	    fprintf(out,"\tI__2 = %d;\n",arg);
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tFASSET__S(I__2,F__0);\n");
	    break;
	case POS_FLOAT:
	    fprintf(out,"\tF__1 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = F__1;\n");
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    break;
	case NEG_FLOAT:
	    fprintf(out,"\tF__1 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = -F__1;\n");
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    break;
	case WRITE_CHAR:
	    fprintf(out,"\tI__2 = %d;\n",arg);
	    fprintf(out,"\tI__0 = AVAL__S(I__2);\n");
	    fprintf(out,"\tprintf(\"%%c\",I__0);\n");
	    break;
	case READ_CHAR:
	    fprintf(out,"\tI__2 = %d;\n",arg);
	    fprintf(out,"\tscanf(\"%%c\",&I__0);\n");
	    fprintf(out,"\tASSET__S(I__2,I__0);\n");
	    break;
	case GREATER_THAN_EQ_INT:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__0 - I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tPUSH__S(1);\n");
	    fprintf(out,"\tif(I__0 >= 0) goto L%d;\n",label_num);
	    fprintf(out,"\tSSET__S(0,0);\n");
	    fprintf(out,"\tL%d:\n",label_num);
	    label_num++;
	    return label_num - 1;
	    break;
	case GREATER_THAN_INT:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__0 - I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tPUSH__S(1);\n");
	    fprintf(out,"\tif(I__0 > 0) goto L%d;\n",label_num);
	    fprintf(out,"\tSSET__S(0,0);\n");
	    fprintf(out,"\tL%d:\n",label_num);
	    label_num++;
	    return label_num - 1;
	    break;
	case LESS_THAN_EQ_INT:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__0 - I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tPUSH__S(1);\n");
	    fprintf(out,"\tif(I__0 <= 0) goto L%d;\n",label_num);
	    fprintf(out,"\tSSET__S(0,0);\n");
	    fprintf(out,"\tL%d:\n",label_num);
	    label_num++;
	    return label_num - 1;
	    break;
	case LESS_THAN_INT:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__0 - I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tPUSH__S(1);\n");
	    fprintf(out,"\tif(I__0 < 0) goto L%d;\n",label_num);
	    fprintf(out,"\tSSET__S(0,0);\n");
	    fprintf(out,"\tL%d:\n",label_num);
	    label_num++;
	    return label_num - 1;
	    break;
	case CMP_EQUAL_INT:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__0 - I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tPUSH__S(1);\n");
	    fprintf(out,"\tif(I__0 == 0) goto L%d;\n",label_num);
	    fprintf(out,"\tSSET__S(0,0);\n");
	    fprintf(out,"\tL%d:\n",label_num);
	    label_num++;
	    return label_num - 1;
	    break;
	case CMP_NOT_EQUAL_INT:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__0 - I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tPUSH__S(1);\n");
	    fprintf(out,"\tif(I__0 != 0) goto L%d;\n",label_num);
	    fprintf(out,"\tSSET__S(0,0);\n");
	    fprintf(out,"\tL%d:\n",label_num);
	    label_num++;
	    return label_num - 1;
	    break;
	case GREATER_THAN_EQ_FLOAT:
	    fprintf(out,"\tF__1 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = F__0 - F__1;\n");
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tPUSH__S(1);\n");
	    fprintf(out,"\tif(F__0 >= 0) goto L%d;\n",label_num);
	    fprintf(out,"\tSSET__S(0,0);\n");
	    fprintf(out,"\tL%d:\n",label_num);
	    label_num++;
	    return label_num - 1;
	    break;
	case GREATER_THAN_FLOAT:
	    fprintf(out,"\tF__1 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = F__0 - F__1;\n");
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tPUSH__S(1);\n");
	    fprintf(out,"\tif(F__0 > 0) goto L%d;\n",label_num);
	    fprintf(out,"\tSSET__S(0,0);\n");
	    fprintf(out,"\tL%d:\n",label_num);
	    label_num++;
	    return label_num - 1;
	    break;
	case LESS_THAN_EQ_FLOAT:
	    fprintf(out,"\tF__1 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = F__0 - F__1;\n");
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tPUSH__S(1);\n");
	    fprintf(out,"\tif(F__0 <= 0) goto L%d;\n",label_num);
	    fprintf(out,"\tSSET__S(0,0);\n");
	    fprintf(out,"\tL%d:\n",label_num);
	    label_num++;
	    return label_num - 1;
	    break;
	case LESS_THAN_FLOAT:
	    fprintf(out,"\tF__1 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = F__0 - F__1;\n");
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tPUSH__S(1);\n");
	    fprintf(out,"\tif(F__0 < 0) goto L%d;\n",label_num);
	    fprintf(out,"\tSSET__S(0,0);\n");
	    fprintf(out,"\tL%d:\n",label_num);
	    label_num++;
	    return label_num - 1;
	    break;
	case CMP_EQUAL_FLOAT:
	    fprintf(out,"\tF__1 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = F__0 - F__1;\n");
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tPUSH__S(1);\n");
	    fprintf(out,"\tif(F__0 == 0) goto L%d;\n",label_num);
	    fprintf(out,"\tSSET__S(0,0);\n");
	    fprintf(out,"\tL%d:\n",label_num);
	    label_num++;
	    return label_num - 1;
	    break;
	case CMP_NOT_EQUAL_FLOAT:
	    fprintf(out,"\tF__1 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tF__0 = F__0 - F__1;\n");
	    fprintf(out,"\tFPUSH__S(F__0);\n");
	    fprintf(out,"\tF__0 = FPOP__S();\n");
	    fprintf(out,"\tPUSH__S(1);\n");
	    fprintf(out,"\tif(F__0 != 0) goto L%d;\n",label_num);
	    fprintf(out,"\tSSET__S(0,0);\n");
	    fprintf(out,"\tL%d:\n",label_num);
	    label_num++;
	    return label_num - 1;
	    break;
	case LOGIC_AND:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__0 & I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    break;
	case LOGIC_OR:
	    fprintf(out,"\tI__1 = POP__S();\n");
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = I__0 | I__1;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    break;
	case LOGIC_NOT:
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tI__0 = !I__0;\n");
	    fprintf(out,"\tPUSH__S(I__0);\n");
	    break;
	case IF_LABEL:
	    fprintf(out,"\tI__0 = POP__S();\n");
	    fprintf(out,"\tif(I__0==0) goto L%d;\n",arg);
	    break;
	case GEN_LABEL:
	    fprintf(out,"\tL%d:\n",arg);
	    break;
	case GOTO:
	    fprintf(out,"\tgoto L%d;\n",arg);
	    break;
	case SWITCH_TEST:
	     break;
	case SET_FOR_INDEX:
	     fprintf(out,"\tI__0 = POP__S();\n");
	     fprintf(out,"\tI__2 = %d\n",arg);
	     fprintf(out,"\tASSET__S(I__2,I__0);\n");
	     fprintf(out,"\tPUSH__S(I__0);\n");
	     break;
	case GET_FOR_INDEX:
	     fprintf(out,"\tI__0 = %d;\n",arg);
	     fprintf(out,"\tI__2 = AVAL__S(I__0);\n");
	     fprintf(out,"\tPUSH__S(I__2);\n");
	     break;
    }
    return 0;
}

void gen_allocated_space(FILE* out, int allocated_space)
{
    /*need add 1 to allocated space for indexing from 1*/
    fprintf(out,"\tASETSP__S(%d);\n",allocated_space+1);
}

int find_allocated_space(int var_num, int var_index, int scope, int *used_scope)
{
	int i;
	for(i=scope;i>=0;i--)
	{
		if(var[var_index][i].addr>0)
		{
			if(used_scope!=NULL)
			{
			    *used_scope = i;
			    return var[var_index][i].addr;
			}
		}
	}
	return -1;
}
